# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal, QPoint, Qt


class SelectableLabel(QtWidgets.QLabel):
    """
    可选择区域的标签控件
    """
    box_sel_img_signal = pyqtSignal(int, int, int, int)  # 框选图像的信号
    process_segmentation_img_signal = pyqtSignal(int, int)  # 处理分割图像的信号
    start_process_distance_signal = pyqtSignal(int, int)  # 开始处理距离的信号
    stop_process_distance_signal = pyqtSignal(int, int)  # 结束处理距离的信号

    def __init__(self, parent=None):
        super(SelectableLabel, self).__init__(parent)
        self.setMouseTracking(True)
        self.open_mouse_flag = False  # 开启鼠标选择框标志
        self.clear_flag = False  # 清除标志
        self.process_flag = False  # 处理分割图像标志
        self.paint_old_point_flag = False  # 绘制旧点的标志

        self.start_x = 0
        self.start_y = 0
        self.end_x = 0
        self.end_y = 0
        self.old_point_x = 0
        self.old_point_y = 0

        self.isMousePressed = False

    def mousePressEvent(self, event):
        if not self.open_mouse_flag:
            return

        # 添加 SAM 选点功能
        if hasattr(self.parent().parent(), 'sam_mode') and self.parent().parent().sam_mode:
            if event.button() == Qt.LeftButton:
                self.parent().parent().sam_add_point(event.x(), event.y(), is_positive=True)
            elif event.button() == Qt.RightButton:
                self.parent().parent().sam_add_point(event.x(), event.y(), is_positive=False)
            return

        self.isMousePressed = True
        self.start_x = event.x()
        self.start_y = event.y()

        if self.process_flag:
            self.process_segmentation_img_signal.emit(event.x(), event.y())
        else:
            self.start_process_distance_signal.emit(event.x(), event.y())

    def mouseMoveEvent(self, event):
        if not self.open_mouse_flag or not self.isMousePressed:
            return

        self.end_x = event.x()
        self.end_y = event.y()
        self.update()

        if self.process_flag:
            self.process_segmentation_img_signal.emit(event.x(), event.y())

    def mouseReleaseEvent(self, event):
        if not self.open_mouse_flag:
            return

        self.isMousePressed = False
        self.end_x = event.x()
        self.end_y = event.y()

        # 如果是清除标志，则发送框选区域信号
        if self.clear_flag:
            # 确保起点在左上角，终点在右下角
            x0 = min(self.start_x, self.end_x)
            y0 = min(self.start_y, self.end_y)
            x1 = max(self.start_x, self.end_x)
            y1 = max(self.start_y, self.end_y)

            # 确保选择的区域不是太小
            if x1 - x0 > 10 and y1 - y0 > 10:
                self.box_sel_img_signal.emit(x0, y0, x1, y1)

        # 如果不是处理分割图像标志，则发送结束处理距离信号
        if not self.process_flag:
            self.stop_process_distance_signal.emit(event.x(), event.y())

        self.update()

    def keyPressEvent(self, event):
        # 添加回车键处理，触发SAM分割
        if hasattr(self.parent().parent(), 'sam_mode') and self.parent().parent().sam_mode:
            if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
                self.parent().parent().sam_segment()
                return
        super(SelectableLabel, self).keyPressEvent(event)

    def paintEvent(self, event):
        super(SelectableLabel, self).paintEvent(event)

        if not self.open_mouse_flag or not self.isMousePressed:
            return

        # 绘制选择框
        if self.clear_flag:
            painter = QtGui.QPainter(self)
            painter.setPen(QtGui.QPen(Qt.red, 2, Qt.SolidLine))
            painter.drawRect(QtCore.QRect(
                QPoint(self.start_x, self.start_y),
                QPoint(self.end_x, self.end_y)
            ))

        # 绘制旧点
        if self.paint_old_point_flag:
            painter = QtGui.QPainter(self)
            painter.setPen(QtGui.QPen(Qt.blue, 2, Qt.SolidLine))
            painter.drawEllipse(
                self.old_point_x - 5,
                self.old_point_y - 5,
                10, 10
            )

    def set_oldPoint(self, x, y):
        """设置旧点坐标"""
        self.old_point_x = x
        self.old_point_y = y


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        # 主窗口设置
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1280, 720)
        MainWindow.setMinimumSize(QtCore.QSize(1200, 700))

        # 中央窗口部件
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        # 创建主布局
        self.mainLayout = QtWidgets.QHBoxLayout(self.centralwidget)

        # 创建左侧布局（用于放置原始图像）
        self.leftLayout = QtWidgets.QVBoxLayout()
        self.leftLayout.setContentsMargins(10, 10, 10, 10)

        # 图像显示标签
        self.lblSourceImage = SelectableLabel(self.centralwidget)
        self.lblSourceImage.setFrameShape(QtWidgets.QFrame.Box)
        self.lblSourceImage.setAlignment(QtCore.Qt.AlignCenter)
        self.lblSourceImage.setObjectName("lblSourceImage")
        self.lblSourceImage.setText("原始图像")
        self.lblSourceImage.setMinimumSize(600, 500)
        self.leftLayout.addWidget(self.lblSourceImage)

        # 创建中间布局（用于放置分割图像和目标对象）
        self.middleLayout = QtWidgets.QVBoxLayout()
        self.middleLayout.setContentsMargins(10, 10, 10, 10)

        # 分割图像标签
        self.lblSegmentedImage = SelectableLabel(self.centralwidget)
        self.lblSegmentedImage.setFrameShape(QtWidgets.QFrame.Box)
        self.lblSegmentedImage.setAlignment(QtCore.Qt.AlignCenter)
        self.lblSegmentedImage.setObjectName("lblSegmentedImage")
        self.lblSegmentedImage.setText("分割图像")
        self.lblSegmentedImage.setMinimumSize(300, 300)
        self.middleLayout.addWidget(self.lblSegmentedImage)

        # 单个对象标签
        self.lblSingleObject = SelectableLabel(self.centralwidget)
        self.lblSingleObject.setFrameShape(QtWidgets.QFrame.Box)
        self.lblSingleObject.setAlignment(QtCore.Qt.AlignCenter)
        self.lblSingleObject.setObjectName("lblSingleObject")
        self.lblSingleObject.setText("目标对象")
        self.lblSingleObject.setMinimumSize(300, 300)
        self.middleLayout.addWidget(self.lblSingleObject)

        # 创建右侧布局（用于放置工具和结果）
        self.rightLayout = QtWidgets.QVBoxLayout()
        self.rightLayout.setContentsMargins(10, 10, 10, 10)

        # 控制按钮和工具面板
        self.groupBoxTools = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBoxTools.setObjectName("groupBoxTools")
        self.groupBoxTools.setTitle("工具")
        self.groupBoxTools.setMinimumSize(300, 300)

        # 创建工具内部布局
        self.toolsLayout = QtWidgets.QVBoxLayout(self.groupBoxTools)

        # 创建按钮网格布局
        self.buttonsGrid = QtWidgets.QGridLayout()

        # 打开图像按钮
        self.btnOpen = QtWidgets.QPushButton(self.groupBoxTools)
        self.btnOpen.setObjectName("btnOpen")
        self.btnOpen.setText("打开图像")
        self.buttonsGrid.addWidget(self.btnOpen, 0, 0)

        # 分割按钮
        self.btnSegment = QtWidgets.QPushButton(self.groupBoxTools)
        self.btnSegment.setObjectName("btnScale")
        self.btnSegment.setText("取比例尺")
        self.buttonsGrid.addWidget(self.btnSegment, 0, 1)

        # 测量按钮
        self.btnMeasure = QtWidgets.QPushButton(self.groupBoxTools)
        self.btnMeasure.setObjectName("btnSampick")
        self.btnMeasure.setText("图像测量")
        self.buttonsGrid.addWidget(self.btnMeasure, 1, 0)

        # SAM模型按钮
        self.btnSAM = QtWidgets.QPushButton(self.groupBoxTools)
        self.btnSAM.setObjectName("btnSAM")
        self.btnSAM.setText("SAM选点")
        self.buttonsGrid.addWidget(self.btnSAM, 1, 1)

        # 擦除按钮
        self.btnErase = QtWidgets.QPushButton(self.groupBoxTools)
        self.btnErase.setObjectName("btnErase")
        self.btnErase.setText("暂未开发")
        self.buttonsGrid.addWidget(self.btnErase, 2, 0)

        # 保存结果按钮
        self.btnSave = QtWidgets.QPushButton(self.groupBoxTools)
        self.btnSave.setObjectName("btnSave")
        self.btnSave.setText("保存结果")
        self.buttonsGrid.addWidget(self.btnSave, 2, 1)

        # 添加按钮网格到工具布局
        self.toolsLayout.addLayout(self.buttonsGrid)

        # 单位比例设置组
        self.groupBoxScale = QtWidgets.QGroupBox(self.groupBoxTools)
        self.groupBoxScale.setObjectName("groupBoxScale")
        self.groupBoxScale.setTitle("比例尺设置")

        # 创建比例尺设置布局
        self.scaleLayout = QtWidgets.QGridLayout(self.groupBoxScale)

        # 实际长度标签和输入框
        self.lblUnitLength = QtWidgets.QLabel(self.groupBoxScale)
        self.lblUnitLength.setObjectName("lblUnitLength")
        self.lblUnitLength.setText("像素数量:")
        self.scaleLayout.addWidget(self.lblUnitLength, 0, 0)

        self.txtUnitLength = QtWidgets.QLineEdit(self.groupBoxScale)
        self.txtUnitLength.setObjectName("txtUnitLength")
        self.scaleLayout.addWidget(self.txtUnitLength, 0, 1)

        # 像素数量标签和输入框
        self.lblUnitPixels = QtWidgets.QLabel(self.groupBoxScale)
        self.lblUnitPixels.setObjectName("lblUnitPixels")
        self.lblUnitPixels.setText("比例尺长:")
        self.scaleLayout.addWidget(self.lblUnitPixels, 1, 0)

        self.txtUnitPixels = QtWidgets.QLineEdit(self.groupBoxScale)
        self.txtUnitPixels.setObjectName("txtUnitPixels")
        self.scaleLayout.addWidget(self.txtUnitPixels, 1, 1)

        # 单位选择部分
        self.unitLayout = QtWidgets.QHBoxLayout()

        # 单位选择
        self.radioUM = QtWidgets.QRadioButton(self.groupBoxScale)
        self.radioUM.setObjectName("radioUM")
        self.radioUM.setText("微米μm")
        self.radioUM.setChecked(True)
        self.unitLayout.addWidget(self.radioUM)

        self.radioMM = QtWidgets.QRadioButton(self.groupBoxScale)
        self.radioMM.setObjectName("radioMM")
        self.radioMM.setText("毫米mm")
        self.unitLayout.addWidget(self.radioMM)

        self.radioM = QtWidgets.QRadioButton(self.groupBoxScale)
        self.radioM.setObjectName("radioM")
        self.radioM.setText("米m")
        self.unitLayout.addWidget(self.radioM)

        # 添加单位布局到比例尺设置布局
        self.scaleLayout.addLayout(self.unitLayout, 2, 0, 1, 2)

        # 添加比例尺设置组到工具布局
        self.toolsLayout.addWidget(self.groupBoxScale)

        # 添加工具组到右侧布局
        self.rightLayout.addWidget(self.groupBoxTools)

        # 结果显示组
        self.groupBoxResults = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBoxResults.setObjectName("groupBoxResults")
        self.groupBoxResults.setTitle("测量结果")
        self.groupBoxResults.setMinimumSize(300, 300)

        # 创建结果布局
        self.resultsLayout = QtWidgets.QVBoxLayout(self.groupBoxResults)

        # 结果文本显示
        self.txtResults = QtWidgets.QTextEdit(self.groupBoxResults)
        self.txtResults.setObjectName("txtResults")
        self.txtResults.setReadOnly(True)
        self.resultsLayout.addWidget(self.txtResults)

        # 添加结果组到右侧布局
        self.rightLayout.addWidget(self.groupBoxResults)

        # 设置左、中、右布局的伸缩因子
        self.mainLayout.addLayout(self.leftLayout, 2)  # 2份空间
        self.mainLayout.addLayout(self.middleLayout, 1)  # 1份空间
        self.mainLayout.addLayout(self.rightLayout, 1)  # 1份空间

        # 设置中央窗口部件
        MainWindow.setCentralWidget(self.centralwidget)

        # 创建状态栏
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        # 创建菜单栏
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1280, 23))
        self.menubar.setObjectName("menubar")

        # 文件菜单
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuFile.setTitle("文件")

        # 帮助菜单
        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")
        self.menuHelp.setTitle("帮助")

        MainWindow.setMenuBar(self.menubar)

        # 添加菜单项
        self.actionOpen = QtWidgets.QAction(MainWindow)
        self.actionOpen.setObjectName("actionOpen")
        self.actionOpen.setText("打开图像")

        self.actionSave = QtWidgets.QAction(MainWindow)
        self.actionSave.setObjectName("actionSave")
        self.actionSave.setText("保存结果")

        self.actionExit = QtWidgets.QAction(MainWindow)
        self.actionExit.setObjectName("actionExit")
        self.actionExit.setText("退出")

        self.actionAbout = QtWidgets.QAction(MainWindow)
        self.actionAbout.setObjectName("actionAbout")
        self.actionAbout.setText("关于")

        # 将菜单项添加到菜单中
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionExit)
        self.menuHelp.addAction(self.actionAbout)

        # 将菜单添加到菜单栏
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        # 设置快捷键
        self.actionOpen.setShortcut("Ctrl+O")
        self.actionSave.setShortcut("Ctrl+S")
        self.actionExit.setShortcut("Ctrl+Q")



